﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace GiteeOpenSdk.WebHook
{
    /// <summary>
    /// 签名验证
    /// </summary>
    public static class SignVerification
    {
        public static string CreateSign(string secret, long timestamp = 0)
        {
            if (timestamp == 0)
            {
                timestamp = GetTimestamp13bit();
            }
            var sign = timestamp.ToString() + "\n" + secret;
            //Step1
            var hash = HmacSHA256(secret, sign);
            //Step2
            sign= Convert.ToBase64String(hash);
            //Step3
            //sign = System.Web.HttpUtility.UrlEncode(sign, System.Text.Encoding.UTF8);
            return sign;
        }
        /// <summary>
        /// 校验Sign
        /// </summary>
        /// <param name="secret"></param>
        /// <param name="timestamp"></param>
        /// <param name="sign"></param>
        /// <returns></returns>
        public static bool CompareSign(string secret, long timestamp, string sign)
        {
            //与请求调用时间误差不能超过1小时
            if (Math.Abs(GetTimestamp13bit() - timestamp) > 1000 * 60 * 60)
            {
                return false;
            }
            return CreateSign(secret, timestamp) == sign;
        }
        //加密算法HmacSHA256  
        private static byte[] HmacSHA256(string secret, string signKey)
        {
            //string signRet = string.Empty;
            using (HMACSHA256 mac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
            {
                byte[] hash = mac.ComputeHash(Encoding.UTF8.GetBytes(signKey));
                //signRet = Convert.ToBase64String(hash);
                //signRet = ToHexString(hash); ;
                return hash;
            }
            //return signRet;
        }

        //byte[]转16进制格式string
        public static string ToHexString(byte[] bytes)
        {
            string hexString = string.Empty;
            if (bytes != null)
            {
                StringBuilder strB = new StringBuilder();
                foreach (byte b in bytes)
                {
                    strB.AppendFormat("{0:x2}", b);
                }
                hexString = strB.ToString();
            }
            return hexString;
        }
        public static long GetTimestamp13bit(DateTime value)
        {
            return new DateTimeOffset(value).ToUnixTimeMilliseconds();
        }
        public static long GetTimestamp13bit()
        {
            return new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds();
        }
    }
}
